package br.trainee.web.componentes;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.inject.Inject;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;

import br.trainee.web.bo.componentes.AutoCompleteBO;

@WebServlet("/autocomplete")
public class AutoCompleteController extends HttpServlet {
	
	private static final long serialVersionUID = 1L;

	@Inject
	private AutoCompleteBO bo;

	@Inject
	private Logger log;
	
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		// Recebendo os valores dos parametros passados por ajax pelo componente autocomplete.
		String className = request.getParameter("className");
		String columnName = request.getParameter("columnName");
		String columnStatusName = request.getParameter("columnStatusName");
		Integer columnStatusValue = Integer.valueOf(request.getParameter("columnStatusValue"));
		String atributeStatusName = request.getParameter("atributeStatusName");
		String keyField = request.getParameter("keyField");
		String keyValue = request.getParameter("keyValue");
		String parameterReturn = request.getParameter("parameterReturn");

		Class classeObjeto = null;
		
		try {
			
			classeObjeto = Class.forName(className);
			
		} catch (ClassNotFoundException e) {
			
			log.log(Level.SEVERE, e.getMessage());
			
		}
		
		bo.setClasseObjeto(classeObjeto);
		
		// Chamando do BO o metodo que retorna uma List.
		List listReturn = bo.retornarLista(className, columnName, parameterReturn, columnStatusName, columnStatusValue, atributeStatusName);
		
		// Criando um vetor vazio.
		String returnJson = "[]";
		
		// Instanciando um JSONArray.
		JSONArray jsonVetor = new JSONArray();

		// Rodando a List usando foreach.
		for(Object o: listReturn){
	
			// Criando dois Fields(key,value) como null.
			Field key = null;
			Field value = null;
			
			try {
				
				// o.getClass retorna a classe do objeto sendo rodado.
				Class userClass = o.getClass();

				// While para verificar em qual classe esta o field buscado, enquanto não achar ele continuara ate ser nulo que significa que não esta na classe nem em nenhuma herança.
				Search:
				while(userClass != null){
					
					// .getDeclaredFields retorna todos os field da classe colocando em um vetor.
					Field campo[] = userClass.getDeclaredFields();
					
					// Criando um contador.
					int contador = 0;
					
					// Rodando o vetor para buscar o field desejado.
					for(int i=0;i<campo.length;i++){

						// Caso o campo rodado seja igual ao keyField o contador recebe +1.
						if(campo[i].getName().equals(keyField)){
							
							contador ++;
							
						}
						// Caso o campo rodado seja igual ao keyValue o contador recebe +1.
						if(campo[i].getName().equals(keyValue)){
							
							contador ++;
							
						}
						// Caso encontre os dois valores o if finalizara o while.
						if(contador == 2){
							
							break Search;
							
						}
						
					}
					
					// Zerando o contador.
					contador = 0;
					
					// Caso não encontre os field desejado , um novo .getSuperclass() buscara não pai da classe corrente.
					userClass = userClass.getSuperclass();
	
				}

				// key recebe o field presente em keyField.
				key = userClass.getDeclaredField(keyField);
				// value recebe o field presente em keyValue.
				value = userClass.getDeclaredField(keyValue);
				
				// Setando permissão de acessibilidade.
				key.setAccessible(true);
				value.setAccessible(true);
								
			} catch (NoSuchFieldException e) {

				log.log(Level.SEVERE, e.getMessage());
				
			} catch (SecurityException e) {

				log.log(Level.SEVERE, e.getMessage());
				
			}
			
			// Criando dois Object com valores nulos.
			Object valueKeyField = null;
			Object valueValueField = null;
			
			try {
				
				// Pegando o valor do field key.
				valueKeyField = (Object) key.get(o);
				// Pegando o valor do field value.
				valueValueField = (Object) value.get(o);
				
			} catch (IllegalArgumentException e) {

				log.log(Level.SEVERE, e.getMessage());
				
			} catch (IllegalAccessException e) {

				log.log(Level.SEVERE, e.getMessage());
				
			}
			
			// Fazendo o Downcasting do value para String.
			String field = (String) valueValueField;
			// Fazendo o Downcasting do key para Long.
			Long id = (Long) valueKeyField;
			
			// Instanciando um JSONObject colocando a chave e o valor.
			JSONObject json = new JSONObject();
			json.put(keyValue, field);
			json.put(keyField, id);
			
			// Adicionando ao vetor de Json o Json corrente.
			jsonVetor.add(json);

		}
		
		// Colocando o jsonVetor em uma String de JSON's.
		returnJson = jsonVetor.toString();
		
		System.out.println(returnJson);
		
		// Mudando o ContentType para application/json.
		response.setContentType("application/json");
		// Retornando por print o Json de retorno.
		response.getWriter().print(returnJson);

	}

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

	}

}
